#pragma once

#include "Common.h"
#include "ThreadCache.h"
#include "PageCache.h"
#include "ObjectPool.h"

// 声明线程局部存储的 ThreadCache 指针
static thread_local ThreadCache *pTLSThreadCache = nullptr;

static void *ConcurrentAlloc(size_t size)
{
	if (size > MAX_BYTES)
	{
		size_t alignSize = SizeClass::RoundUp(size);
		size_t kpage = alignSize >> PAGE_SHIFT;

		PageCache::GetInstance()->_pageMtx.lock();
		Span *span = PageCache::GetInstance()->NewSpan(kpage);
		if (span == nullptr) {
            PageCache::GetInstance()->_pageMtx.unlock();
            throw std::bad_alloc();
        }
		span->_objSize = size;
		PageCache::GetInstance()->_pageMtx.unlock();

		void *ptr = (void *)(span->_pageId << PAGE_SHIFT);
		return ptr;
	}
	else
	{
		// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象
		if (pTLSThreadCache == nullptr)
		{
			static ObjectPool<ThreadCache> tcPool;
			// pTLSThreadCache = new ThreadCache;
			pTLSThreadCache = tcPool.New();
			if (pTLSThreadCache == nullptr)
			{
				throw std::bad_alloc(); // 或 fallback 到全局分配
			}
		}

		// cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;

		return pTLSThreadCache->Allocate(size);
	}
}

static void ConcurrentFree(void *ptr)
{
	if (ptr == nullptr) return; // 避免释放空指针

	Span *span = PageCache::GetInstance()->MapObjectToSpan(ptr);
	if (span == nullptr)
	{
		std::cerr << "Invalid pointer freed!" << std::endl;
		return;
	}

	size_t size = span->_objSize;
	if (size > MAX_BYTES)
	{
		PageCache::GetInstance()->_pageMtx.lock();
		PageCache::GetInstance()->ReleaseSpanToPageCache(span);
		PageCache::GetInstance()->_pageMtx.unlock();
	}
	else
	{
		 if (pTLSThreadCache == nullptr) {
            std::cerr << "ThreadCache not initialized!" << std::endl;
            return;
        }
		pTLSThreadCache->Deallocate(ptr, size);
	}
}